﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace DrawTools.Controls.ColorSelector
{
  [ToolboxItem(false)]
  public sealed class ColorSelectorPopup : ToolStripDropDown
  {
    private bool _isColorSelected;

    public event EventHandler<ColorSelectionEventArgs> ColorSelected;

    public event EventHandler RestoreColor;

    public int ColorItemSize { get; set; }

    public ColorSelectorPopup(IEnumerable<Color> palette, Color currentColor)
    {
      ColorItemSize = 24;
      Padding = new Padding(3);
      Margin = Padding.Empty;

      var colorsPanel = new FlowLayoutPanel
      {
        AutoSize = true,
        AutoSizeMode = AutoSizeMode.GrowAndShrink,
        Location = Point.Empty,
        Margin = Padding.Empty,
        MinimumSize = new Size(16, 16)
      };

      foreach (Color color in palette)
      {
        var colorItem = new ColorItemControl
        {
          Size = new Size(ColorItemSize, ColorItemSize),
          BackColor = color,
          HoverBorderColor = Color.White,
          BorderColor = Color.Black,
          Location = new Point(0, 0),
          Margin = new Padding(2),
          Padding = new Padding(0),
          IsChecked = currentColor.ToArgb() == color.ToArgb() //http://msdn.microsoft.com/en-us/library/e03x8ct2(v=vs.110).aspx
        };

        colorItem.MouseEnter += OnColorItemMouseEnter;
        colorItem.MouseClick += OnColorItemMouseClick;

        colorsPanel.Controls.Add(colorItem);
      }

      var host = new ToolStripControlHost(colorsPanel)
      {
        Margin = Padding.Empty,
        Padding = Padding.Empty
      };

      Items.Add(host);
    }

    protected override void OnClosing(ToolStripDropDownClosingEventArgs e)
    {
      if (!_isColorSelected)
        InvokeRestoreColor();
    }

    protected override void OnKeyDown(KeyEventArgs e)
    {
      if (e.KeyCode == Keys.Escape)
      {
        InvokeRestoreColor();
        Close();
      }
    }

    private void OnColorItemMouseEnter(object sender, EventArgs e)
    {
      var colorItem = sender as ColorItemControl;

      if (colorItem == null)
        return;

      InvokeColorSelected(colorItem.BackColor);
    }

    private void OnColorItemMouseClick(object sender, MouseEventArgs e)
    {
      var colorItem = sender as ColorItemControl;

      if (colorItem == null)
        return;

      if (e.Button == MouseButtons.Left)
      {
        _isColorSelected = true;
        InvokeColorSelected(colorItem.BackColor);
      }
      else
      {
        InvokeRestoreColor();
      }

      Close();
    }

    private void InvokeColorSelected(Color color)
    {
      EventHandler<ColorSelectionEventArgs> handler = ColorSelected;
      if (handler != null)
      {
        handler(this, new ColorSelectionEventArgs
        {
          SelectedColor = color
        });
      }
    }

    private void InvokeRestoreColor()
    {
      EventHandler handler = RestoreColor;
      if (handler != null)
        handler(this, EventArgs.Empty);
    }
  }
}